package com.enki.cigarettes.controller;

import com.enki.cigarettes.controller.vo.response.ProductsFollowResponseVo;
import com.enki.cigarettes.entity.ProductFollowT;
import com.enki.cigarettes.entity.ProductPictureT;
import com.enki.cigarettes.entity.ProductSkuT;
import com.enki.cigarettes.entity.ProductT;
import com.enki.cigarettes.enums.ProductEnums;
import com.enki.cigarettes.handler.Response;
import com.enki.cigarettes.repository.*;
import com.enki.cigarettes.statics.StaticKeys;
import com.enki.cigarettes.utils.PrimaryKey;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * @author WCS.Wang
 * @version V1.0
 * @Package com.enki.cigarettes.controller
 * @Name e-cigarettes-shop-api-module
 * @Description: TODO 商品收藏数据层
 * @date 2019-07-19
 */
@RestController
@RequestMapping("/api/follow/products")
@Slf4j
public class ProductFollowController {

    @Autowired
    ProductFollowTRepository productFollowTRepository;
    @Autowired
    ProductTRepository productTRepository;
    @Autowired
    ProductSkuTRepository productSkuTRepository;
    @Autowired
    ProductPictureTRepository productPictureTRepository;
    @Autowired
    ProductCommentTRepository productCommentTRepository;

    @ApiOperation(value = "商品收藏")
    @ApiImplicitParam(name = "productId", value = "商品ID", dataType = "long", required = true)
    @PostMapping(value = "/{productId}")
    public Object save(@PathVariable long productId, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            ProductT productBean = productTRepository.findOneByIdAndStatus(productId, ProductEnums.ProductStatus.ONTHSHELF.getType());
            if (productBean == null) {
                return Response.notFound_404("不存在的商品信息");
            }
            List<ProductSkuT> productSkuBeans = productSkuTRepository.findByProductTIdAndStatus(productBean.getId(), ProductEnums.ProductSkuStatus.ONTHESHELF.getType(), new Sort(Sort.Direction.DESC, "sales"));
            ProductSkuT productSkuBean = null;
            if (productSkuBeans.size() > 0) {
                productSkuBean = productSkuBeans.get(0);
            }
            // 保存收藏信息
            ProductFollowT productFollow = productFollowTRepository.findOneByUserTIdAndProductId(sessionId.toString(), productId);
            if (productFollow == null) {
                ProductFollowT bean = new ProductFollowT();
                bean.setId(PrimaryKey.get().toString());
                bean.setUserTId(sessionId.toString());
                bean.setProductId(productId);
                bean.setOldPrice(productSkuBean.getSalePrice());
                bean.setNowPrice(productSkuBean.getSalePrice());
                bean.setProductSkuId(productSkuBean.getId());
                bean.setCreateTime(new Date());
                productFollowTRepository.save(bean);
            }
            return Response.success();
        } catch (Exception e) {
            log.error("保存商品收藏失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，保存商品收藏失败");
        }
    }


    @ApiOperation(value = "取消收藏")
    @ApiImplicitParam(name = "id", value = "商品ID", dataType = "long", required = true)
    @DeleteMapping(value = "/{id}")
    public Object del(@PathVariable long id, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            // 删除收藏信息
            ProductFollowT productFollow = productFollowTRepository.findOneByUserTIdAndProductId(sessionId.toString(), id);
            if (productFollow != null) {
                productFollowTRepository.delete(productFollow);
            }
            return Response.success();
        } catch (Exception e) {
            log.error("取消商品收藏失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，取消商品收藏失败");
        }
    }

    @ApiOperation(value = "获取收藏商品列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", required = true, dataType = "int"),
            @ApiImplicitParam(name = "size", value = "每页数据", required = true, dataType = "int")
    })
    @GetMapping
    public Object findByPage(@RequestParam(value = "page", defaultValue = "0") int page, @RequestParam(value = "size", defaultValue = "10") int size, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            Sort sort = new Sort(Sort.Direction.DESC, StaticKeys.SORT_CREATE_TIME);
            Pageable pageable = PageRequest.of(page, size, sort);
            Specification<ProductFollowT> specification = new Specification<ProductFollowT>() {
                @Override
                public Predicate toPredicate(Root<ProductFollowT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    Root<ProductT> productTRoot = query.from(ProductT.class);
                    predicateList.add(criteriaBuilder.equal(root.get("productId"), productTRoot.get("id")));
                    predicateList.add(criteriaBuilder.equal(root.get("userTId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(productTRoot.get("status"), ProductEnums.ProductStatus.ONTHSHELF.getType()));
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            Page<ProductFollowT> beanPage = productFollowTRepository.findAll(specification, pageable);
            List<ProductsFollowResponseVo> vos = new ArrayList<>();
            for (ProductFollowT bean : beanPage.getContent()) {
                ProductT product = productTRepository.findOneById(bean.getProductId());
                if (product != null) {
                    ProductsFollowResponseVo voBean = new ProductsFollowResponseVo();
                    voBean.setId(String.valueOf(product.getId()));
                    voBean.setName(product.getName());
                    voBean.setTitle(product.getTitle());
                    // 最低价格
                    List<ProductSkuT> productSkuBeanList = productSkuTRepository.findByProductTIdAndStatus(product.getId(), ProductEnums.ProductSkuStatus.ONTHESHELF.getType(), new Sort(Sort.Direction.ASC,"salePrice"));
                    if(productSkuBeanList.size() > 0) {
                        voBean.setPrice(Double.valueOf(productSkuBeanList.get(0).getSalePrice()) / 100 + "");
                    } else {
                        voBean.setPrice(Double.valueOf(product.getLowestPrice()) / 100 + "");
                    }
                    // 商品主图
                    List<ProductPictureT> pictureList = productPictureTRepository.findByProductTIdAndIsMaster(product.getId(), true);
                    if (pictureList.size() >= 1) {
                        voBean.setPicture(pictureList.get(0).getPhotoPath());
                    }
                    // 商品评论数量
                    Long commentCount = productCommentTRepository.countByProductTId(product.getId());
                    voBean.setCommentCount(commentCount);
                    // 好评率
                    Long praiseCount = productCommentTRepository.countByProductTIdAndScoreGreaterThanEqual(product.getId(), 5);
                    // 好评率
                    if (commentCount > 0 && praiseCount > 0) {
                        Double praise = (praiseCount.doubleValue() / commentCount.doubleValue());
                        BigDecimal bg = new BigDecimal(praise).setScale(2, RoundingMode.UP);
                        voBean.setPraise(bg.doubleValue() * 100);
                    } else {
                        voBean.setPraise(0.00);
                    }
                    vos.add(voBean);
                }
            }
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("content", vos);
            responseData.put("number", beanPage.getNumber());
            responseData.put("totalPages", beanPage.getTotalPages());
            responseData.put("totalElements", beanPage.getTotalElements());
            responseData.put("size", beanPage.getSize());
            responseData.put("last", beanPage.isLast());
            return Response.success(responseData, StaticKeys.SUCCESS);
        } catch (Exception e) {
            log.error("获取商品收藏失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，获取商品收藏失败");
        }

    }

}
